﻿
namespace HSS.Xaml.UI.Controls
{
	#region Using Directives
	using System.Windows;
	using HSS.ComponentModel;
	using System.Windows.Controls;
	using System;
	#endregion

	#region StringValueEditor
	/// <summary>
	/// A String value editor.
	/// </summary>
	public class StringValueEditor : PropertyGridEditor
	{
		#region Fields
		LabelTextBox inlineEditor;
		ChildWindow dialog;
		Button button;
		bool isReadOnly;
		#endregion

		#region Constructors
		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="descriptor"></param>
		public StringValueEditor(HSSPropertyDescriptor descriptor)
			: base(descriptor)
		{
			this.isReadOnly = descriptor.IsReadOnly || !descriptor.CanWrite;
			this.button = new Button();
			this.button.Margin = new System.Windows.Thickness(0);
			this.button.Padding = new System.Windows.Thickness(4, 1, 4, 1);
			this.button.Content = "...";
		}
		#endregion

		#region Overrides
		/// <summary>
		/// Gets the button that will be clicked to show the Dialog Editor.
		/// </summary>
		/// <returns>The <see cref="System.Windows.Controls.Button"/> to be rendered.</returns>
		public override System.Windows.Controls.Button GetDialogEditButton()
		{
			return button;
		}
		/// <summary>
		/// Gets if this editor support showing a Dialog Editor.
		/// </summary>
		public override bool SupportsEditDialog
		{
			get { return base.Descriptor.PropertyType == typeof(string); }
		}
		/// <summary>
		/// Shows the Dialog Editor.
		/// </summary>
		protected override void ShowEditDialogInternal()
		{
			if (null != this.dialog)
				this.dialog.Close();
			if (null == this.inlineEditor)
				this.dialog = new MultilineStringEditorDialog(this.Object.ToString()) { Title = "Edit - " + this.Descriptor.Name, ReadOnly = this.isReadOnly };
			else
				this.dialog = new MultilineStringEditorDialog(this.inlineEditor.Text) { Title = "Edit - " + this.Descriptor.Name, ReadOnly = this.isReadOnly };
			this.dialog.Closed += new EventHandler(dialog_Closed);
			this.dialog.Show();
		}
		/// <summary>
		/// This is called prior to executing the default action allowing the
		/// editor to prepare for a new edit cycle.
		/// </summary>
		/// <remarks>
		/// This action is invoked by the user DoubleClicking the Entry Label
		/// </remarks>
		public override void PrepareExecuteDefaultAction()
		{
			this.ShouldSelectAllText = true;
		}
		/// <summary>
		/// Creates the Inline Editor control.
		/// </summary>
		/// <returns>The control as a FrameworkElement.</returns>
		protected override FrameworkElement CreateInlineEditControl()
		{
			if (this.Descriptor.PropertyType == typeof(string))
				this.inlineEditor = new LabelTextBox() { AcceptsReturn = true };
			else
				this.inlineEditor = new LabelTextBox();
			return this.inlineEditor;
		}
		protected override void InitializeInlineEditControl()
		{
			if (null != this.Object)
				this.inlineEditor.Text = this.Object.ToString();
		}
		/// <summary>
		/// Gets the current value held by the control.
		/// </summary>
		/// <returns>The object.</returns>
		protected override object GetControlValue()
		{
			return this.inlineEditor.Text;
		}
		/// <summary>
		/// Updates the editor with the new value.
		/// </summary>
		/// <param name="newValue">The new value.</param>
		protected override void UpdateInlineEditControl(object newValue)
		{
			if (newValue is char)
			{
				if ((char)newValue == '\0')
					this.inlineEditor.Text = string.Empty;
				else
					this.inlineEditor.Text = newValue.ToString();
			}
			else if (newValue is string)
			{
				this.inlineEditor.Text = (string)newValue;
			}
			else
			{
				this.inlineEditor.Text = this.ValueToString(newValue);
			}

			if (this.ShouldSelectAllText)
			{
				this.inlineEditor.SelectAll();
				this.ShouldSelectAllText = false;
			}
		}
		#endregion

		#region Event Handlers
		void dialog_Closed(object sender, EventArgs e)
		{
			this.dialog.Closed -= new EventHandler(dialog_Closed);
			var d = dialog as MultilineStringEditorDialog;
			this.dialog = null;
			if (this.isReadOnly)
			{
				this.CancelEdit();
			}
			else
			{
				if (d.DialogResult == true)
				{
					this.inlineEditor.Text = d.Value;
					this.EndEdit();
				}
				else
					this.CancelEdit();
			}
		}
		#endregion
	}
	#endregion
}